package org.zjx.entity;

import lombok.Data;
import lombok.NoArgsConstructor;
import org.zjx.model.game.Screen;

import java.io.Serializable;
import java.util.Objects;

/**
 * 游戏内位置坐标实体类
 * 表示游戏中的一个具体位置，包含场景、房间和坐标信息
 */
@Data
@NoArgsConstructor
public class Location implements Serializable {
    private static final long serialVersionUID = 1L;
    private Screen screen;
    private int x;            // X坐标
    private int y;            // Y坐标


    /**
     * 完整构造函数
     *
     * @param screen 场景
     * @param x      X坐标
     * @param y      Y坐标
     * @throws IllegalArgumentException 如果场景名称为空
     */
    public Location(Screen screen, int x, int y) {
        if (screen == null) {
            throw new IllegalArgumentException("Scene cannot be empty");
        }
        this.screen = screen;
        this.x = x;
        this.y = y;
    }

    /**
     * 判断是否同场景
     *
     * @param other 另一个位置
     * @return 如果场景相同返回true
     */
    public boolean sameScene(Location other) {
        return this.screen.getId() == other.getScreen().getId();
    }


    public boolean isRoom() {
        return this.screen.getFatherId() != 0;
    }


    /**
     * 判断是否同场景且距离过近
     *
     * @param other 另一个位置
     * @return 如果场景相同且过近返回true
     * 判断是否邻近（同场景且距离<=10像素）
     */
    public boolean isNear(Location other) {
        return sameScene(other) && distanceTo(other) <= 10.0;
    }

    /**
     * 计算同场景内的距离
     *
     * @param other 另一个位置
     * @return 两点之间的距离(像素单位)
     * @throws IllegalArgumentException 如果不在同一场景
     */
    public double distanceTo(Location other) {
        if (!sameScene(other)) {
            throw new IllegalArgumentException("Cannot calculate distance between different scenes");
        }
        int dx = this.x - other.x;
        int dy = this.y - other.y;
        return Math.sqrt(dx * dx + dy * dy);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Location location = (Location) o;
        return x == location.x &&
                y == location.y &&
                screen.getId() == location.screen.getId();
    }

    @Override
    public int hashCode() {
        return Objects.hash(screen, x, y);
    }

    /**
     * 转换为字符串表示
     *
     * @return 格式化的位置字符串
     */
    @Override
    public String toString() {
        return String.format("%s[%d,%d]", screen.getName(), x, y);
    }
}